package com.wss.common.wechat.spi.biz;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.wss.common.context.util.HttpRequestProxyUtil;
import com.wss.common.context.util.SystemConfig;
import com.wss.common.wechat.exception.WeixinException;
import com.wss.common.wechat.massage.InputMessage;
import com.wss.common.wechat.massage.MsgType;
import com.wss.common.wechat.massage.OutputMessage;
import com.wss.common.wechat.massage.app.AuthInputMessage;
import com.wss.common.wechat.massage.normal.output.TextOutputMessage;
import com.wss.common.wechat.spi.IMessageHandler;
import com.wss.common.wechat.spi.app.event.IAppEventMessageHandler;
import com.wss.common.wechat.spi.biz.normal.INormalMessageHandler;
import com.wss.common.wechat.util.WeChatInterfaceUtil;
import com.wss.common.wechat.util.weixin.XStreamFactory;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.StringReader;
import java.util.Date;


/**
 * @author 赵飞
 * @version 用于处理微信消息
 */
@Component("bizMessageHandler")
public class BizMessageHandler implements IMessageHandler {


	private static Logger log = Logger.getLogger(BizMessageHandler.class);
	//普通消息处理
	@Autowired
	private INormalMessageHandler normalMessageHandler;
	//应用级消息处理（处理全网发布检测）
	@Autowired
	private IAppEventMessageHandler appEventMessageHandler;

	@Override
	public String invoke(ServletInputStream inputStream) throws WeixinException {
		try {
			//将输入流转换为字符串
			String xmlMsg = XStreamFactory.inputStream2String(inputStream);
			if (true) {
				System.out.println("获取POST的消息:");
				System.out.println(xmlMsg);
				System.out.println("------------------------");
			}
			return this.invoke(xmlMsg);
		} catch (IOException ex) {
			throw new WeixinException("输入流转换错误：", ex);
		}
	}

	@Override
	public String invoke(String inputXml) throws WeixinException {
		//输出消息对象
		OutputMessage outputMsg = null;
		try {
			JAXBContext context = JAXBContext.newInstance(InputMessage.class);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			InputMessage inputMsg = (InputMessage) unmarshaller.unmarshal(new StringReader(inputXml));
			if (SystemConfig.isDebug()) {
				log.info("将指定节点下的xml节点数据转换为对象成功!");
			}
			// 取得消息类型
			String msgType = inputMsg.getMsgType();

			if (SystemConfig.isDebug()) {
				log.info("POST的消息类型:[msgType:" + msgType+"]");

			}


			/**
			 * 在处理微信消息前，必定需要匹配公众号，然后基于公众号的配置进行反馈
			 */
			if (SystemConfig.TEST_GH_ID.equals(inputMsg.getToUserName())) {
				//全网发布粉丝消息检测
				if (MsgType.Event.toString().equals(msgType)) {
					/**
					 * 1、模拟粉丝触发专用测试公众号的事件，并推送事件消息到专用测试公众号，
					 *    第三方平台方开发者需要提取推送XML信息中的event值，
					 *    并在5秒内立即返回按照下述要求组装的文本消息给粉丝。
					 */
					TextOutputMessage textOutputMessage = new TextOutputMessage();
					textOutputMessage.setContent(inputMsg.getEvent() + "from_callback");
					outputMsg = textOutputMessage;
				} else if (MsgType.Text.toString().equals(msgType)) {
					//模拟粉丝发送文本消息给专用测试公众号
					if ("TESTCOMPONENT_MSG_TYPE_TEXT".equals(inputMsg.getContent())) {
						/**
						 * 2、测试立即回复
						 */
						TextOutputMessage textOutputMessage = new TextOutputMessage();
						textOutputMessage.setContent("TESTCOMPONENT_MSG_TYPE_TEXT_callback");
						outputMsg = textOutputMessage;
					} else if (inputMsg.getContent().contains("QUERY_AUTH_CODE")) {
						/**
						 * 异步回复
						 */
						//获取测试公众号预授权码
						String query_auth_code = inputMsg.getContent().replace("QUERY_AUTH_CODE:","");
						AuthInputMessage msg = new AuthInputMessage();
						msg.setAuthorizationCode(query_auth_code);
						appEventMessageHandler.authTypeMsg(msg);

						new Thread(new Runnable() {
							@Override
							public void run() {
								//调用客服接口异步回复文本消息
								JsonParser jsonParser = new JsonParser();
								JsonObject jsonParam = new JsonObject();
								jsonParam.addProperty("touser", inputMsg.getToUserName());
								jsonParam.addProperty("msgtype", "text");
								JsonObject textJson = new JsonObject();
								textJson.addProperty("content",query_auth_code+"_from_api");
								jsonParam.add("text",textJson);
								String jsonStr = null;
								try {
									jsonStr = HttpRequestProxyUtil.executeJsonParamHttpPost(WeChatInterfaceUtil.getMessageCustomSend(inputMsg.getAppId()), jsonParam.toString());
								} catch (Exception e) {
									log.info("微信客服接口报错！",e);
								}
								log.info("客服消息接口调用返回：" + jsonStr);
								if (jsonStr != null && !"".equals(jsonStr)) {
									JsonObject jsonObject = jsonParser.parse(jsonStr).getAsJsonObject();
									if (jsonObject.has("errcode")&&jsonObject.get("errcode").getAsInt()==0) {
										log.info("已通过客服消息接口异步处理微信消息");
									}
								}

							}
						}).start();

						return ""; //暂不回复

					}

				}

				if (outputMsg != null) {
					//设置收件人消息
					setOutputMsgInfo(outputMsg, inputMsg);
				}

			}
		} catch (IOException ex) {
			throw new WeixinException("输入流转换错误：", ex);
		} catch (NoSuchMethodException ex) {
			throw new WeixinException("没有找打对应方法：", ex);
		} catch (SecurityException ex) {
			throw new WeixinException("安全错误：", ex);
		} catch (Exception ex) {
			throw new WeixinException("系统错误：", ex);
		}
		if (outputMsg != null) {
			try {
				// 把发送发送对象转换为xml输出
				String xml = outputMsg.toXML();
				if (SystemConfig.isDebug()) {
					System.out.println("POST输出消息:");
					System.out.println(xml);
					System.out.println("------------------------");
				}
				return xml;
			} catch (Exception ex) {
				throw new WeixinException("转换回复消息为xml时错误：", ex);
			}
		}
		return "";
	}

	//设置详细信息
	private static void setOutputMsgInfo(OutputMessage oms, InputMessage msg) throws Exception {
		// 设置发送信息
		oms.setCreateTime(new Date().getTime());
		oms.setToUserName(msg.getFromUserName());
		oms.setFromUserName(msg.getToUserName());
	}

}
